/*
 *   Copyright (C) 2010  Jens Kieselbach
 * 
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 * 
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 * 
 *   You may obtain a copy of the License at http://www.gnu.org/licenses/gpl.html
 */

package de.kieselbach.swing

import java.awt.event.*
import javax.swing.*
import javax.swing.event.*
import javax.swing.text.*
import javax.swing.undo.*

class PlainEditorPane extends JEditorPane implements UndoableEditListener {

    def undoManager = new UndoManager()

    PlainEditorPane() {
        
        getDocument().addUndoableEditListener(this)

        registerKeyboardAction({if (undoManager.canUndo()) {undoManager.undo()}} as ActionListener, KeyStroke.getKeyStroke('control Z'), WHEN_FOCUSED)
        registerKeyboardAction({if (undoManager.canRedo()) {undoManager.redo()}} as ActionListener, KeyStroke.getKeyStroke('control Y'), WHEN_FOCUSED)
    }

    @Override
    public void setDocument(Document doc) {

        if (doc != null) {
            if(getDocument() != null) {
                getDocument().removeUndoableEditListener(this)
            }
            super.setDocument(doc);
            getDocument().addUndoableEditListener(this);
        }
    }

    @Override
    public void setText(String text) {

        undoManager.discardAllEdits()
        super.setText(text)
    }

    public void undoableEditHappened(UndoableEditEvent e) {

        undoManager.addEdit(e.getEdit())
    }

    public int getLineOfOffset(int offset) throws BadLocationException {

        Document doc = getDocument()
        if (offset < 0) {
            throw new BadLocationException("Can't translate offset to line", -1)
        }
        else if (offset > doc.getLength()) {
            throw new BadLocationException("Can't translate offset to line", doc.getLength()+1)
        }
        else {
            Element map = getDocument().getDefaultRootElement()
            return map.getElementIndex(offset)
        }
    }

    public int getLineStartOffset(int line) throws BadLocationException {

        int lineCount = getLineCount()
        if (line < 0) {
            throw new BadLocationException("Negative line", -1)
        }
        else if (line >= lineCount) {
            throw new BadLocationException("No such line", getDocument().getLength()+1)
        }
        else {
            Element map = getDocument().getDefaultRootElement()
            Element lineElem = map.getElement(line)
            return lineElem.getStartOffset()
        }
    }

    public int getLineCount() {
        
        Element map = getDocument().getDefaultRootElement()
        return map.getElementCount()
    }
}

